package com.vision.util.http;

import org.apache.http.Consts;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.nio.charset.CodingErrorAction;
import java.security.KeyStore;

/**
 * 项目名称：vision
 * 类名称： HttpFactory
 * 类描述：
 * 创建人：zc
 * 创建时间：2017-01-18 19:03
 * 修改人：
 * 修改时间：
 * 修改备注：
 *
 * @version 1.0
 */
public class HttpFactory2 extends AbsHttpFactory {

    private CloseableHttpClient httpClient;
    private RequestConfig requestConfig;

    public HttpFactory2(int socketTimeOut, int connectTimeOut, int requestTimeOut, String BEST_MATCH) {
        super(socketTimeOut, connectTimeOut, requestTimeOut, BEST_MATCH);
    }

    public HttpFactory2(String proxyIp, int socketTimeOut, int connectTimeOut, int requestTimeOut, String BEST_MATCH) {
        super(proxyIp, socketTimeOut, connectTimeOut, requestTimeOut, BEST_MATCH);
    }


    public HttpFactory2(String proxyIp, Integer proxyPort, int socketTimeOut, int connectTimeOut, int requestTimeOut) {
        super(proxyIp, proxyPort, socketTimeOut, connectTimeOut, requestTimeOut);
    }

    public HttpFactory2(String proxyIp, Integer proxyPort, int socketTimeOut, int connectTimeOut, int requestTimeOut, String BEST_MATCH) {
        super(proxyIp, proxyPort, socketTimeOut, connectTimeOut, requestTimeOut, BEST_MATCH);
    }

    void init() {
        PoolingHttpClientConnectionManager connManager = null;
        try {
            System.setProperty("https.protocols", "TLSv1.1");
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            SSLContext sslContext = SSLContexts.custom().useProtocol("TLS").loadTrustMaterial(trustStore, (TrustStrategy) (x509Certificates, s) -> true).build();
            LayeredConnectionSocketFactory sslSF = SSLConnectionSocketFactory.getSocketFactory();
            RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
            registryBuilder.register("http", sslSF);
            registryBuilder.register("https", sslSF);

            Registry<ConnectionSocketFactory> socketFactoryRegistry = registryBuilder.build();
            connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
            connManager.setDefaultSocketConfig(socketConfig);

            ConnectionConfig connectionConfig =
                    ConnectionConfig.custom().setMalformedInputAction(CodingErrorAction.IGNORE)
                            .setUnmappableInputAction(CodingErrorAction.IGNORE).setCharset(Consts.UTF_8).build();
            connManager.setDefaultConnectionConfig(connectionConfig);
            connManager.setMaxTotal(300);
            connManager.setDefaultMaxPerRoute(100);
            HttpClientBuilder httpClientBuilder =
                    HttpClients.custom().setConnectionManager(connManager)
                            .setDefaultCookieStore(new BasicCookieStore())
                            .setUserAgent(userAgent)
                            .setSSLContext(sslContext);
            if (proxy != null) {
                httpClientBuilder.setRoutePlanner(new DefaultProxyRoutePlanner(proxy)).build();
            }
            httpClient = httpClientBuilder.build();

            requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeOut).
                    setConnectTimeout(connectTimeOut).
                    setConnectionRequestTimeout(requestTimeOut).
                    setCookieSpec(BEST_MATCH != null ? BEST_MATCH : CookieSpecs.DEFAULT).
                    build();
        } catch (Exception e) {
            if (connManager != null) {
                connManager.close();
            }
            throw new RuntimeException("error", e);
        }
    }


    public CloseableHttpClient getHttpClient() {
        return httpClient;
    }

    public RequestConfig getRequestConfig() {
        return requestConfig;
    }
}
